package com.gxp.util.security;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.gxp.pojo.Authority;
import com.gxp.pojo.Role;
import com.gxp.pojo.User;
import com.gxp.service.UserService;

/**
 * Custom {@link UserDetailsService} which retrieves the data for the user authenticatiing from the database. When the
 * user exists returns a {@link GxpUserDetails} containing all inforamtion for further authentication
 * 
 * @author Marten Deinum
 * @author Koen Serneels
 * 
 */
@Component
public class GxpUserDetailsService implements UserDetailsService {
	
	Logger log = Logger.getLogger(GxpUserDetailsService.class);

	@Autowired
	private UserService userService;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		log.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~invoke GxpUserDetailsService.loadUserByUsername");
		if (StringUtils.isBlank(username)) {
			throw new UsernameNotFoundException("Username was empty");
		}

		User usertemp = new User();
		usertemp.setUserId(username);
		User user = userService.findByUserIdForLogin(usertemp);

		if (user == null) {
			throw new UsernameNotFoundException("Username not found");
		} else {
			log.debug("user name: " + user.getUserId());
		}

		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();

		for (Role role : user.getRoleList()) {
			grantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName()));
			log.debug("role: " + role.getRoleName());
			for (Authority permission : role.getPermissionList()) {
				grantedAuthorities.add(new SimpleGrantedAuthority(permission.getAuthName()));
				log.debug("permission: " + permission.getAuthName());
			}
		}
		return new GxpUserDetails(user, grantedAuthorities);
	}
}
